function addNode(parentId, nodeId, nodeLable, position) {
    var panel = d3.select("#" + parentId);
    panel.append('div').style('width', '120px').style('height', '70px')
        .style('position', 'absolute')
        .style('top', position.y).style('left', position.x)
        .style('border', '2px #9DFFCA solid').attr('align', 'center')
        .attr('id', nodeId).classed('node', true)
        .text(nodeLable);

    var s_id = nodeId+"_script"
    $('#' + nodeId).append('<div class = "prop"><input type="text"/></div>')

    var f = '#' + nodeId+ " input"
    $(f).attr('id', s_id).width("100px")




    return jsPlumb.getSelector('#' + nodeId)[0];
}

function addPorts(instance, node, ports, type) {
    //Assume horizental layout
    var number_of_ports = ports.length;
    var i = 0;
    var height = $(node).height();  //Note, jquery does not include border for height
    var y_offset = 1 / (number_of_ports + 1);
    var y = 0;

    for (; i < number_of_ports; i++) {
        var anchor = [0, 0, 0, 0];
        var paintStyle = {radius: 5, fillStyle: '#5f54ff'};
        var isSource = false, isTarget = false;
        if (type === 'output') {
            anchor[0] = 1;
            paintStyle.fillStyle = '#37ff2f';
            isSource = true;
        } else {
            isTarget = true;
        }

        anchor[1] = y + y_offset;
        y = anchor[1];

        instance.addEndpoint(node, {
            uuid: node.getAttribute("id") + "-" + ports[i],
            paintStyle: paintStyle,
            anchor: anchor,
            maxConnections: -1,
            isSource: isSource,
            isTarget: isTarget
        });

    }
}

function connectPorts(instance, node1, port1, node2, port2) {
    // declare some common values:
    var color = "gray";
    var arrowCommon = {foldback: 0.8, fillStyle: color, width: 5},
        // use three-arg spec to create two different arrows with the common values:
        overlays = [
            ["Arrow", {location: 0.8}, arrowCommon],
            ["Arrow", {location: 0.2, direction: -1}, arrowCommon]
        ];

    var uuid_source = node1.getAttribute("id") + "-" + port1;
    var uuid_target = node2.getAttribute("id") + "-" + port2;

    instance.connect({uuids: [uuid_source, uuid_target]});

}

// 选中父节点时，选中所有子节点
function getChildNodeIdArr(node) {
    var ts = [];
    if (node.nodes) {
        for (x in node.nodes) {
            ts.push(node.nodes[x].nodeId);
            if (node.nodes[x].nodes) {
                var getNodeDieDai = getChildNodeIdArr(node.nodes[x]);
                for (j in getNodeDieDai) {
                    ts.push(getNodeDieDai[j]);
                }
            }
        }
    } else {
        ts.push(node.nodeId);
    }
    return ts;
}

function getTreeData() {
    var tree = [
        {
            text: "数据接入",
            backColor:'#d1ffe2',
            nodes: [
                {
                    text: "flume",
                },
                {
                    text: "sqoop"
                }
            ]
        },
        {
            text: "数据清洗",
            backColor:'#d1ffe2',
            nodes: [
                {
                    text: "缺失值处理",
                },
                {
                    text: "数据过滤"
                }
            ]
        },
        {
            text: "分布式计算",
            backColor:'#d1ffe2',
            state:{
                expanded:false
            },
            nodes: [
                // {
                //     text: "spark",
                // },
                // {
                //     text: "hive"
                // }
            ]
        },
        {
            text: "数据挖掘",
            backColor:'#d1ffe2',
            state:{
                expanded:false
            },
            nodes: [
                // {
                //     text: "线性回归",
                // },
                // {
                //     text: "SVM"
                // }
            ]
        }
    ];

    return tree;
}

jsPlumb.ready(function () {
    console.log("jsPlumb is ready to use");

    //Initialize JsPlumb
    var color = "#E8C870";
    var instance = jsPlumb.getInstance({
        // notice the 'curviness' argument to this Bezier curve.  the curves on this page are far smoother
        // than the curves on the first demo, which use the default curviness value.
        Connector: ["Bezier", {curviness: 50}],
        DragOptions: {cursor: "pointer", zIndex: 2000},
        PaintStyle: {strokeStyle: color, lineWidth: 2},
        EndpointStyle: {radius: 5, fillStyle: color},
        HoverPaintStyle: {strokeStyle: "#7073EB"},
        EndpointHoverStyle: {fillStyle: "#7073EB"},
        Container: "flow-panel"
    });

    //Initialize Control Tree View
    $('#control-panel').treeview({
        data: getTreeData(),
        // onNode: function (event, data) {
        //
        //     var id = parseInt(data.nodeId);
        //     var id1 = (id+1).toString()
        //     $("[data-nodeid=id1]").attr('draggable', 'true')
        //     console.log(111);
        // }
    });

    $('#control-panel').click(function(){
        $('.list-group-item ').attr('draggable', 'true');
    });


    //
    //Handle drag and drop
    $('.list-group-item ').attr('draggable', 'true').on('dragstart', function (ev) {
        //ev.dataTransfer.setData("text", ev.target.id);
        ev.originalEvent.dataTransfer.setData('text', ev.target.textContent);
        console.log('drag start');
    });


    instance.bind("connection", function (info) {
        getFlowInfo();
    });

    $('#flow-panel').on('drop', function (ev) {

        //avoid event conlict for jsPlumb
        if (ev.target.className.indexOf('_jsPlumb') >= 0) {
            return;
        }


        ev.preventDefault();
        var mx = '' + ev.originalEvent.offsetX + 'px';
        var my = '' + ev.originalEvent.offsetY + 'px';

        console.log('on drop : ' + ev.originalEvent.dataTransfer.getData('text'));
        var node_name = ev.originalEvent.dataTransfer.getData('text')
        var uid = new Date().getTime();
        var node = addNode('flow-panel', 'node-' + node_name + "-" + uid, node_name, {x: mx, y: my});
        addPorts(instance, node, ['out'], 'output');
        addPorts(instance, node, ['in1', 'in2'], 'input');
        instance.draggable($(node));

        getFlowInfo();
    }).on('dragover', function (ev) {
        ev.preventDefault();
        console.log('on drag over');

    });

    function getFlowInfo() {
        //=========================================================
        var data = {}
        var nodes = []

        $("#flow-panel .node").each(function (idx, elem) {
            var $elem = $(elem);
            var b_id = $elem.attr('id');
            var ss = $("#"+b_id+"_script").val()
            nodes.push({
                uuid: $elem.attr('id'),
                property:{
                  script:  ss,
                },
                positionX: parseInt($elem.css("left"), 10),
                positionY: parseInt($elem.css("top"), 10)
            });
        });

        var connections = [];
        $.each(instance.getAllConnections(), function (idx, connection) {
            var endpoints = connection.endpoints;
            var connect = {}
            var endpoint0 = {}
            var endpoint1 = {}
            endpoint0.uuid = endpoints[0].getUuid()
            endpoint0.isSource = endpoints[0].isSource
            endpoint0.isTarget = endpoints[0].isTarget

            endpoint1.uuid = endpoints[1].getUuid()
            endpoint1.isSource = endpoints[1].isSource
            endpoint1.isTarget = endpoints[1].isTarget

            connect.endpoint0 = endpoint0;
            connect.endpoint1 = endpoint1;
            connect.connectionId = connection.id;
            connect.sourceId = connection.sourceId;
            connect.targetId = connection.targetId;
            connect.sourceText = connection.source.innerText;
            connect.targetText = connection.target.innerText;

            connections.push({
                connect
            });
        });

        data.nodes = nodes;
        data.connections = connections;

        console.log(JSON.stringify(data))
    }

    instance.doWhileSuspended(function () {

    });

    jsPlumb.fire("jsFlowLoaded", instance);

});